package com.ruoyi.web.websocket;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSON;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.robot.domain.InterfaceSetting;
import com.ruoyi.robot.domain.UserChatData;
import com.ruoyi.robot.service.IChatRobotSettingService;
import com.ruoyi.robot.service.IInterfaceSettingService;
import com.ruoyi.robot.service.IUserChatDataService;
import com.ruoyi.web.controller.tool.SendMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

//webSocket服务类
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocket {

    private IUserChatDataService userChatDataService;

    private IInterfaceSettingService interfaceSettingService;

    private static ConcurrentHashMap<String, WebSocket> webSocketMap = new ConcurrentHashMap<>();

    //实例化一个session
    private Session session;

    //开启一个链接，把请求账户加入到会话webSocketMap里,并返回连接成功字样
    @OnOpen
    public void onOpen(@PathParam("userId") String userId,Session session) {
        this.session = session;
        webSocketMap.put(userId,this);
        sendMessage("CONNECT_SUCCESS", userId);
    }
    //关闭连接，删除相应账户会话
    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        webSocketMap.remove(userId);
    }
    //发送、接收消息
    /*
    消息格式：
        name - 发送人名称
        nameId - 发送人ID
        toName - 接收人名称
        toId - 接收人ID
        content - 发送内容
        reply - 收到的回复
        userfile - 发送文件名
        robotfile - 接受文件名
        userfilename - 发送文件完成名称(含路径)
        robotfilename - 接收文件完成名称(含路径)
        flag - 消息ID(同一消息四个状态ID一致)
        msgtype - 消息状态 :msg,robot，engineer(已作废)
        position - 消息状态值域:[0,1,2,3],
        状态0：初始发送的文本，状态1：收到分词的文本，状态2：确认分词的文本，状态3：确认的最终回复
    * */
    @OnMessage
    public void onMessage(String message, Session session) {
        //API列表中的名字
        String infSplitWord = "/chat/splitword";
        String infConfirmWord = "/chat/confirmWord";

        try
        {

            UserChatData userChatData = new UserChatData();

            //websocket多实例，而spring为单例
            userChatDataService = SpringUtils.getBean(IUserChatDataService.class);
            interfaceSettingService = SpringUtils.getBean(IInterfaceSettingService.class);

            InterfaceSetting infSpltWordServ = interfaceSettingService.selectInterfaceSettingByInterfaceName(infSplitWord);
            InterfaceSetting infConfirmWordServ = interfaceSettingService.selectInterfaceSettingByInterfaceName(infConfirmWord);

            //日常读值，传给usrChatData实体
            JSONObject msg = JSONObject.parseObject(message);
            userChatData = SendMsg.setMsgToChatEntity(msg);

            //需要更新的值
            String nameId = msg.getString("nameId");
            String toId = msg.getString("toId");
            String content = msg.getString("content");
            String reply = msg.getString("reply");
            String msgtype = msg.getString("msgtype");
            String step = msg.getString("position");

            //状态判断
            if("0".equals(step))
            {
                userChatDataService.insertUserChatData(userChatData);
                msgtype = "bot";
                reply = "";
                step = "1";
                //默认数据格式化，按单字分行
                reply = SendMsg.formatDataByWrap(content);
                //收到消息，传入接口
                if(infSpltWordServ != null)
                {

                    JSONObject result = SendMsg.postMsg(infSpltWordServ.getInterfaceAddr(),userChatData);
                    if(result != null && result.containsKey("reply"))
                    {
                        reply = result.getString("reply");
                    }
                }
                msg.put("msgtype",msgtype);
                msg.put("reply",reply);
                msg.put("position",step);
                userChatData.setMsgtype(msgtype);
                userChatData.setReply(reply);
                userChatData.setPosition(step);
                userChatDataService.insertUserChatData(userChatData);
                sendMessage(msg,nameId);
            }
            else if("2".equals(step))
            {

                reply = reply.replaceAll("\n","");
                if(infConfirmWordServ != null)
                {
                    JSONObject result = SendMsg.postMsg(infConfirmWordServ.getInterfaceAddr(),userChatData);
                    if(result != null && result.containsKey("reply"))
                    {
                        reply = result.getString("reply");
                    }
                }
                msg.put("reply",reply);
                userChatData.setReply(reply);
                userChatDataService.insertUserChatData(userChatData);
                sendMessage(msg,nameId);
            }
            else if("3".equals(step))
            {
                userChatDataService.insertUserChatData(userChatData);
                sendMessage(msg,toId);
            }
            else
            {

            }

        }catch(Exception e)
        {
            e.printStackTrace();
        }

    }
    //发送消息
    public static void sendMessage(Object message,String userId)
    {
        //取出相应会话
        WebSocket webSocket = webSocketMap.get(userId);
        if(webSocket != null)
        {
            try
            {
                //getBasicRemote发送同步消息，看情况也可使用getAsyncRemote()发送异步消息
                webSocket.session.getBasicRemote().sendText(JSONUtils.toJSONString(message));

            }catch(Exception e)
            {
                e.printStackTrace();
            }
        }
        else
        {
            System.out.println("the session does not exists");
        }
    }



}
